package com.erpanderp.wam.adm.view;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.event.AjaxBehaviorEvent;
import javax.servlet.http.HttpSession;

import com.erpanderp.wam.adm.model.entity.Module;
import com.erpanderp.wam.adm.model.entity.Permission;
import com.erpanderp.wam.adm.model.entity.Resource;
import com.erpanderp.wam.adm.model.entity.Service;
import com.erpanderp.wam.adm.model.service.ModuleDAO;
import com.erpanderp.wam.adm.model.service.PermissionDAO;
import com.erpanderp.wam.adm.model.service.ResourceDAO;
import com.erpanderp.wam.adm.model.service.ServiceDAO;
import com.erpanderp.wam.usm.model.entity.user.WAMUser;
import com.erpanderp.wam.util.CommonLookup;
import com.erpanderp.wam.util.ValidationUtil;

@ManagedBean
@ViewScoped
public class PermissionsBean implements Serializable {

	HttpSession session = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(true);
	private WAMUser wamUser = (WAMUser) session.getAttribute(CommonLookup.SESSION_ATTRIBUTE_WAMUSER);
	
	PermissionDAO permissionDAO = new PermissionDAO();
	private List<Permission> permissions = new ArrayList<Permission>();
	private boolean NO_PERMISSIONS_FOUND;
	private boolean renderNewPermissionPanel;
	
	private Map<String, Long> modulesMap = new HashMap<String, Long>();
	private Map<String, Long> servicesMap = new HashMap<String, Long>();
	private Map<String, Long> resourcesMap = new HashMap<String, Long>();
	private Map<String, String> permissionsMap = new HashMap<String, String>();
	
	private Long selectedModuleId;
	private Long selectedServiceId;
	private Long selectedResourceId;
	private String selectedPermission;
	private String permissionDisplayName;
	
	ModuleDAO moduleDAO = new ModuleDAO();
	ServiceDAO serviceDAO = new ServiceDAO();
	ResourceDAO resourceDAO = new ResourceDAO();
	
	boolean FORM_VALID;
	
	public PermissionsBean(){
		permissions = permissionDAO.getAllPermissions();
		if(permissions != null && permissions.size() > 0){
			NO_PERMISSIONS_FOUND = false;
		}else{
			NO_PERMISSIONS_FOUND = true;
		}
	}
	
	public void addNewPermissionButtonActionListener(ActionEvent e){
		System.out.println("Action Listener...");
		List list = moduleDAO.getAllModules();
		for(Module module : (ArrayList<Module>) list){
			modulesMap.put(module.getModuleName(), module.getModuleId());			
		}
		permissionsMap = CommonLookup.getPermissionsMap();
		setRenderNewPermissionPanel(true);
	}

	public void moduleChangeListener(AjaxBehaviorEvent e){
		servicesMap.clear();
		resourcesMap.clear();
		List<Service> services = serviceDAO.getServicesByModuleId(selectedModuleId);
		for(Service service : services){
			servicesMap.put(service.getDisplayName(), service.getServiceId());
		}		
	}
	
	public void serviceChangeListener(AjaxBehaviorEvent e){
		resourcesMap.clear();
		List<Resource> resources = resourceDAO.getResourcesByServiceId(selectedServiceId);
		for(Resource resource : resources){
			resourcesMap.put(resource.getDisplayName(), resource.getResourceId());
		}		
	}
	
	public void savePermission(ActionEvent e){
		validateForm();
		
		if(FORM_VALID){
			Permission permission = new Permission();
			permission.setCreateDate(new Date());
			permission.setCreatedBy(wamUser.getEmployee().getFirstName());
			permission.setDisplayName(permissionDisplayName);
			permission.setModule(moduleDAO.getModuleById(selectedModuleId));
			permission.setPermission(selectedPermission);
			permission.setResource(resourceDAO.getResourceById(selectedResourceId));
			permission.setService(serviceDAO.getServiceById(selectedServiceId));
			permission.setStatus(CommonLookup.STATUS_ACTIVE);
			if(permissionDAO.createPermission(permission) != null){
				FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Permission created successfully.", ""));
			}else{
				FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Failed to create permission.", ""));
			}		
			
			reset();
			
			//Retrieve permissions from database...
			permissions = permissionDAO.getAllPermissions();
			if(permissions != null && permissions.size() > 0){
				NO_PERMISSIONS_FOUND = false;
			}else{
				NO_PERMISSIONS_FOUND = true;
			}	
		}
			
	}
	
	private void validateForm() {
		FORM_VALID = true;

		if (ValidationUtil.isNonZero(selectedModuleId, "Module",
				null, FacesContext.getCurrentInstance()) != null) {
			FORM_VALID = false;
		}
		if (ValidationUtil.isNonZero(selectedServiceId, " Service", null,
				FacesContext.getCurrentInstance()) != null) {
			FORM_VALID = false;
		}
		if (ValidationUtil.isNonZero(selectedResourceId, "Resource",
				null, FacesContext.getCurrentInstance()) != null) {
			FORM_VALID = false;
		}
		
		if (ValidationUtil.isEmpty(selectedPermission, "Permission ",
				null, FacesContext.getCurrentInstance()) != null) {
			FORM_VALID = false;
		}else if(!permissionDAO.isPermissionAvailable(selectedPermission)){
			FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, "Selected Permission is not available.", ""));
			FORM_VALID = false;			
		}
		
		if (ValidationUtil.isEmpty(permissionDisplayName, "Permission Display Name",
				null, FacesContext.getCurrentInstance()) != null) {
			FORM_VALID = false;
		}else if(!permissionDAO.isPermissionDisplayNameAvailable(permissionDisplayName)){
			FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, "Display Name is not available.", ""));
			FORM_VALID = false;		
		}
	}
	
	public void discard(ActionEvent e){
		reset();
	}
	
	private void reset(){
		//reset fields
		modulesMap.clear();
		resourcesMap.clear();
		servicesMap.clear();
		permissionsMap.clear();
		selectedModuleId = null;
		selectedPermission = null;
		selectedServiceId = null;
		selectedResourceId = null;
		permissionDisplayName = null;
		
		setRenderNewPermissionPanel(false);
	}
	
	public List<Permission> getPermissions() {
		return permissions;
	}

	public void setPermissions(List<Permission> permissions) {
		this.permissions = permissions;
	}

	public boolean isNO_PERMISSIONS_FOUND() {
		return NO_PERMISSIONS_FOUND;
	}

	public void setNO_PERMISSIONS_FOUND(boolean nO_PERMISSIONS_FOUND) {
		NO_PERMISSIONS_FOUND = nO_PERMISSIONS_FOUND;
	}

	public boolean isRenderNewPermissionPanel() {
		return renderNewPermissionPanel;
	}

	public void setRenderNewPermissionPanel(boolean renderNewPermissionPanel) {
		this.renderNewPermissionPanel = renderNewPermissionPanel;
	}

	public Map<String, Long> getModulesMap() {
		return modulesMap;
	}

	public void setModulesMap(Map<String, Long> modulesMap) {
		this.modulesMap = modulesMap;
	}

	public Map<String, Long> getServicesMap() {
		return servicesMap;
	}

	public void setServicesMap(Map<String, Long> servicesMap) {
		this.servicesMap = servicesMap;
	}

	public Map<String, Long> getResourcesMap() {
		return resourcesMap;
	}

	public void setResourcesMap(Map<String, Long> resourcesMap) {
		this.resourcesMap = resourcesMap;
	}

	public Map<String, String> getPermissionsMap() {
		return permissionsMap;
	}

	public void setPermissionsMap(Map<String, String> permissionsMap) {
		this.permissionsMap = permissionsMap;
	}

	public Long getSelectedModuleId() {
		return selectedModuleId;
	}

	public void setSelectedModuleId(Long selectedModuleId) {
		this.selectedModuleId = selectedModuleId;
	}

	public Long getSelectedServiceId() {
		return selectedServiceId;
	}

	public void setSelectedServiceId(Long selectedServiceId) {
		this.selectedServiceId = selectedServiceId;
	}

	public Long getSelectedResourceId() {
		return selectedResourceId;
	}

	public void setSelectedResourceId(Long selectedResourceId) {
		this.selectedResourceId = selectedResourceId;
	}

	public String getSelectedPermission() {
		return selectedPermission;
	}

	public void setSelectedPermission(String selectedPermission) {
		this.selectedPermission = selectedPermission;
	}

	public WAMUser getWamUser() {
		return wamUser;
	}

	public void setWamUser(WAMUser wamUser) {
		this.wamUser = wamUser;
	}

	public String getPermissionDisplayName() {
		return permissionDisplayName;
	}

	public void setPermissionDisplayName(String permissionDisplayName) {
		this.permissionDisplayName = permissionDisplayName;
	}
}
